// 求任意个数字的和
function sum() {
    var res = 0
    for (var i = 0; i < arguments.length; i++) {
        res += arguments[i]
    }
    return res
}

// 查询字符串转成对象
function parseQueryString(str) {
    var obj = {}
    var res = str.split('&')
    res.forEach(function (item) {
        obj[item.split('=')[0]] = item.split('=')[1]
    })
    return obj
}

// 把对象转成查询字符串

function queryString(obj) {
    var str = ''
    for (var k in obj) {
        str += k + '=' + obj[k] + '&'
    }
    str = str.slice(0, -1)
    return str
}

// 获取范围内的随机数
function randomNum(a, b) {
    var res = Math.floor(Math.random() * (Math.abs(a - b) + 1)) + Math.min(a, b)
    return res
}
// 生成随机颜色
function randomColor() {
    var str = ''
    var r = randomNum(0, 255)
    var g = randomNum(0, 255)
    var b = randomNum(0, 255)
    str = `rgb(${r}, ${g}, ${b})`
    return str
}

// 获取时间差
function diffTime(t1, t2) {
    return {
        day: parseInt(Math.ceil(Math.abs(t1 - t2) / 1000) / (24 * 60 * 60)),
        hours: parseInt(Math.ceil(Math.abs(t1 - t2) / 1000) % (24 * 60 * 60) / (60 * 60)),
        minutes: parseInt(Math.ceil(Math.abs(t1 - t2) / 1000) % (60 * 60) / 60),
        seconds: Math.ceil(Math.abs(t1 - t2) / 1000) % 60
    }
}

// 运动函数封装
function move(ele, options, fn) {
    let count = 0
    for (let k in options) {
        count++
        if (k === 'opacity') {
            options[k] = options[k] * 100
        }
        let time = setInterval(() => {
            let start
            if (k === 'opacity') {
                start = window.getComputedStyle(ele)[k] * 100
            } else {
                start = parseInt(window.getComputedStyle(ele)[k])
            }
            let moveDistance = (options[k] - start) / 10

            if (moveDistance > 0) {
                moveDistance = Math.ceil((options[k] - start) / 10)
            } else {
                moveDistance = Math.floor((options[k] - start) / 10)
            }
            if (k === 'opacity') {
                ele.style[k] = (start + moveDistance) / 100
            } else {
                ele.style[k] = start + moveDistance + 'px'
            }
            if (start === options[k]) {
                clearInterval(time)
                count--
                if (count === 0) {
                    fn && fn()
                }
            }
        }, 20)
    }
}

// ajax 封装
function ajax(options) {
    if (Object.prototype.toString.call(options) !== '[object Object]') {
        throw new Error('你传递的不是一个对象,这里需要一个对象数据类型')
    }
    const { url, method, async, data, headers, dataType, success, error } = options
    if (!url || typeof url !== 'string') {
        throw new Error('url必须要传递而且是一个字符串数据类型')
    }
    if (!(method === undefined || /^(get|post)$/i.test(method))) {
        throw new Error('请求方式必须是get或者是post你传递的不对')
    }
    if (!(async === undefined || typeof async === 'boolean')) {
        throw new Error('你传递的不是一个布尔值,这里需要一个布尔值')
    }
    if (!(data === undefined || typeof data === 'string' || Object.prototype.toString.call(data) === '[object Object]')) {
        throw new Error('你传递的数据不符合我们的要求,必须是字符串或者是对象')
    }
    if (!(data === undefined || typeof data === 'string' || Object.prototype.toString.call(data) === '[object Object]')) {
        throw new Error('你传递的数据不符合我们的要求,必须是字符串或者是对象')
    }
    if (!(headers === undefined || Object.prototype.toString.call(headers) === '[object Object]')) {
        throw new Error('你传递的数据不符合我们的要求,必须是一个对象数据类型')
    }
    if (!(dataType === undefined || /^(string|json)$/i.test(dataType))) {
        throw new Error('传递的数据类不对 必须是字符串或者是json')
    }
    if (!(success === undefined || typeof success === 'function')) {
        throw new Error('传递的数据类不对 必须是一个函数')
    }
    if (!(error === undefined || typeof error === 'function')) {
        throw new Error('传递的数据类不对 必须是一个函数')
    }
    let _default = {
        url: url,
        method: method || 'get',
        async: typeof async === 'boolean' ? async : true,
        // async: async ?? true // ?? 空值运算
        data: data || '',
        headers: { 'content-type': 'application/x-www-form-urlencoded', ...headers },
        dataType: dataType || 'string',
        success: success || function () { },
        error: error || function () { }
    }
    if (typeof data === 'object') {
        _default.data = queryString(data)
    }
    if (/^get$/i.test(_default.method) && data) {
        _default.url = _default.url + '?' + _default.data
    }
    const xhr = new XMLHttpRequest()
    xhr.open(_default.method, _default.url, _default.async)
    xhr.onload = function () {
        let res = xhr.responseText
        if (_default.dataType === 'json') {
            res = JSON.parse(xhr.responseText)
            try {
                _default.success(res)
            } catch (err) {
                _default.error(err)
            }
        } else {
            _default.success(res)
        }
    }
    for (let k in _default.headers) {
        xhr.setRequestHeader(k, _default.headers[k])
    }
    if (/^get$/i.test(_default.method)) {
        xhr.send()
    } else {
        xhr.send(_default.data)
    }
}

// 封装promise版本的ajax

function pAjax(options) {
    // 这里需要返回一个promise对象
    // 需要有一个promise对象
    let p = new Promise(function (resolve, rejected) {
        ajax({
            url: options.url,
            data: options.data,
            async: options.async,
            method: options.method,
            headers: options.headers,
            dataType: options.dataType,
            success(res) {
                resolve(res)
            },
            error(err) {
                rejected(err)
            }
        })
    })
    return p
}